package net.jueb.client;

import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;

/**
 * 客户端和服务端的代码非常相似，都是占用一个端口，然后广播数据和接收数据
 * 唯一不同的是，客户端handler中是主动广播请求消息。
 * @author helin
 *
 */
public class UdpClient {

	/**
	 * 面向无连接的协议，只有本地使用的端口，无目的地址，目的地址只存在于数据包内
	 * @param bindPort
	 */
	public void start(int bindPort,int serverPort)
	{
		NioEventLoopGroup group=new NioEventLoopGroup();
		Bootstrap bt=new Bootstrap();
		bt.group(group);
		bt.channel(NioDatagramChannel.class);
		bt.option(ChannelOption.SO_BROADCAST,true);//广播开启
		bt.handler(new UdpClientHandler(serverPort));
		try {
			ChannelFuture cf=bt.bind(bindPort).sync();
			System.out.println("UDP客户端启动成功,端口："+bindPort);
			//可以在这里使用管道进行发送消息，也可以在handler的管道激活事件里面发送广播消息
//			send(cf.channel(),serverPort);
			cf.channel().closeFuture().sync();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			group.shutdownGracefully();
		}
	}
	
	/**
	 * 发送数据包
	 * @param c
	 * @param targetPort 数据包要达到的目标端口
	 */
	private void send(Channel c,int targetPort)
	{
		for(int i=1;i<=10;i++)
		{
			ByteBuf msg=Unpooled.copiedBuffer("Hello Server!".getBytes(CharsetUtil.UTF_8));
			//向所有地址发送
//			c.writeAndFlush(new DatagramPacket(msg, new InetSocketAddress("255.255.255.255",port)));
			//向指定地址发送
			c.writeAndFlush(new DatagramPacket(msg, new InetSocketAddress("192.168.34.158",targetPort)));
		}
	}
	public static void main(String[] args) {
		new UdpClient().start(81,80);
	}
}
